package com.avoscloud.chat.ui.view;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.media.MediaRecorder;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.example.studycard.R;
import com.avoscloud.chat.base.App;

import java.io.File;
import java.io.IOException;

public class RecordButton extends Button {
	public static final int BACK_RECORDING = R.drawable.chat_voice_bg_pressed;
	public static final int BACK_IDLE = R.drawable.chat_voice_bg;
	public static final int SLIDE_UP_TO_CANCEL = 0;// 手指上滑，取消发送
	public static final int RELEASE_TO_CANCEL = 1;// 手指上滑后松开手指取消录音
	private static final int MIN_INTERVAL_TIME = 1000;// 录音最少时间，若时间太短，给出提示“说多点吧”
	private static int[] recordImageIds = { R.drawable.chat_icon_voice0,
			R.drawable.chat_icon_voice1, R.drawable.chat_icon_voice2,
			R.drawable.chat_icon_voice3, R.drawable.chat_icon_voice4,
			R.drawable.chat_icon_voice5 };
	private TextView textView;
	private String outputPath = null;
	private RecordEventListener recordEventListener;// 录音事件监听
	private long startTime;// 开始录音的时间
	private Dialog recordIndicator;
	private View view;
	private MediaRecorder recorder;
	private ObtainDecibelThread thread;
	private Handler volumeHandler;
	private ImageView imageView;
	private int status;
	private OnDismissListener onDismiss = new OnDismissListener() {

		@Override
		public void onDismiss(DialogInterface dialog) {
			stopRecording();
		}
	};

	public RecordButton(Context context) {
		super(context);
		init();
	}

	public RecordButton(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public RecordButton(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	// 设置保存路径
	public void setSavePath(String path) {
		outputPath = path;
	}

	public void setRecordEventListener(RecordEventListener listener) {
		recordEventListener = listener;
	}

	private void init() {
		volumeHandler = new ShowVolumeHandler();
		setBackgroundResource(BACK_IDLE);
		initRecordDialog();
	}

	// 监听手指触摸事件
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		if (outputPath == null)
			return false;
		int action = event.getAction();
		switch (action) {
		case MotionEvent.ACTION_DOWN:
			startRecord();
			break;
		case MotionEvent.ACTION_UP:
			if (status == RELEASE_TO_CANCEL) {
				cancelRecord();
			} else {
				finishRecord();
			}
			break;
		case MotionEvent.ACTION_MOVE:
			if (event.getY() < 0) {
				status = RELEASE_TO_CANCEL;
			} else {
				status = SLIDE_UP_TO_CANCEL;
			}
			setTextViewByStatus();
			break;
		case MotionEvent.ACTION_CANCEL:
			cancelRecord();
			break;
		}
		return true;
	}

	public int getColor(int id) {
		return getContext().getResources().getColor(id);
	}

	private void setTextViewByStatus() {
		if (status == RELEASE_TO_CANCEL) {
			textView.setTextColor(getColor(R.color.red));
			textView.setText(R.string.releaseToCancel);
		} else if (status == SLIDE_UP_TO_CANCEL) {
			textView.setTextColor(getColor(R.color.white));
			textView.setText(R.string.slideUpToCancel);
		}
	}

	private void startRecord() {
		startTime = System.currentTimeMillis();// 开始录音时获取系统时间
		setBackgroundResource(BACK_RECORDING);
		startRecording();
		recordIndicator.show();
	}

	private void initRecordDialog() {
		recordIndicator = new Dialog(getContext(),
				R.style.like_toast_dialog_style);

		view = inflate(getContext(), R.layout.record_layout, null);
		imageView = (ImageView) view.findViewById(R.id.imageView);
		textView = (TextView) view.findViewById(R.id.textView);
		recordIndicator.setContentView(view, new LayoutParams(
				ViewGroup.LayoutParams.WRAP_CONTENT,
				ViewGroup.LayoutParams.WRAP_CONTENT));
		recordIndicator.setOnDismissListener(onDismiss);

		LayoutParams lp = recordIndicator.getWindow().getAttributes();
		lp.gravity = Gravity.CENTER;
	}

	private void finishRecord() {
		stopRecording();
		recordIndicator.dismiss();
		setBackgroundResource(BACK_IDLE);

		long intervalTime = System.currentTimeMillis() - startTime;
		if (intervalTime < MIN_INTERVAL_TIME) {
			Toast.makeText(getContext(),
					getContext().getString(R.string.pleaseSayMore),
					Toast.LENGTH_SHORT).show();
			File file = new File(outputPath);
			file.delete();
			return;
		}

		int sec = Math.round(intervalTime * 1.0f / 1000);
		if (recordEventListener != null) {
			recordEventListener.onFinishedRecord(outputPath, sec);
		}
	}

	private void cancelRecord() {
		stopRecording();
		setBackgroundResource(BACK_IDLE);
		recordIndicator.dismiss();
		Toast.makeText(getContext(), App.ctx.getString(R.string.cancelRecord),
				Toast.LENGTH_SHORT).show();
		File file = new File(outputPath);
		if (file.exists()) {
			file.delete();
		}
	}

	/*
	 * Recorder的startRecording方法启动了java层的录音。
	 * startRecording方法中首先创建一个Mediarecorder的类
	 * ，然后调用Mediarecorder的方法完成设置audio源、设置输出文件格式、audio编码格式、设置输出文件
	 * 然后检查MediaRecorder是否准备好了
	 * 。如果准备好就启动。如果没有准备好就抛出异常然后重新设置MediaRecorder和释放MediaRecorder
	 */
	private void startRecording() {
		if (recorder == null) {
			recorder = new MediaRecorder();
			recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);// 设置用于录制的音源
			recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);// 设置在录制过程中产生的输出文件的格式
			recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);// 设置视频编码器，用于录制
			recorder.setOutputFile(outputPath);// 传入要写入的文件的文件描述符
			try {
				recorder.prepare();// 准备recorder开始捕获和编码数据
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			recorder.reset();// 重新启动MediaRecorder到空闲状态
			recorder.setOutputFile(outputPath);
		}
		recorder.start();
		thread = new ObtainDecibelThread();
		thread.start();
		recordEventListener.onStartRecord();
	}

	private void stopRecording() {
		if (thread != null) {
			thread.exit();
			thread = null;
		}
		if (recorder != null) {
			recorder.stop();
			recorder.release();
			recorder = null;
		}
	}

	public interface RecordEventListener {
		public void onFinishedRecord(String audioPath, int secs);

		void onStartRecord();
	}

	private class ObtainDecibelThread extends Thread {
		private volatile boolean running = true;

		// 若是退出则停止录音
		public void exit() {
			running = false;
		}

		@Override
		public void run() {
			while (running) {
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				if (recorder == null || !running) {
					break;
				}
				// 返回最大振幅的绝对值
				int x = recorder.getMaxAmplitude();
				if (x != 0) {
					int f = (int) (10 * Math.log(x) / Math.log(10));
					int index = (f - 18) / 5;
					if (index < 0)
						index = 0;
					if (index > 5)
						index = 5;
					volumeHandler.sendEmptyMessage(index);
				}
			}
		}

	}

	class ShowVolumeHandler extends Handler {
		@Override
		public void handleMessage(Message msg) {
			imageView.setImageResource(recordImageIds[msg.what]);
			// imageView.setImageResource(recordImageIds[5]);
		}
	}
}
